package com.blog.token;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.blog.Config;
import io.jsonwebtoken.*;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.time.LocalDate;
import java.util.*;

/**
 * 2 * @Author: Tcj
 * 3 * @Date: 2020/11/5 17:56
 * 4
 */
public class TokenUtil {

    /**
     * token黑名单
     */
    private static Set<String> blackList = new HashSet<>();
    public static void addBlackList(String str){
        blackList.add(str);
    }

    /**
     * 验证token是否在黑名单
     * @param str
     * @return
     */
    public static boolean verifyToken(String str){
        if (blackList.contains(str)){
            return true;
        }
        return false;
    }
    /**
     * 生成token
     * @param user
     * @return
     */
    public static String getToken( Object user){

        //签名算法，选择SHA-256
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        //获取当前系统时间
        long nowTimeMillis = System.currentTimeMillis();
        Date now = new Date(nowTimeMillis);
        Map<String,Object> map = JSON.parseObject(JSON.toJSONString(user),new TypeReference<Map<String,Object>>(){});
        JwtBuilder builder = Jwts.builder()
                .signWith(signatureAlgorithm, Config.TOKEN_SECRET)
                .setClaims(map)//设置用户信息
                .setIssuer("user")//签发者
                .setIssuedAt(now)//签发时间
                .setExpiration(new Date(nowTimeMillis +Config.EXPIRE_TIME))//设置过期时间
                ;
        return builder.compact();
    }

    /**
     * 验证token
     * @param token
     * @return
     */
    public static Claims validToken(String token){
        Claims claims = null;
        try {
             claims = Jwts.parser()
                    .setSigningKey(Config.TOKEN_SECRET)
                    .parseClaimsJws(token)
                    .getBody();

        }catch (Exception e){
            return null;
        }
        return claims;
    }
    public static Object getInfo(Object obj, Claims claims){
        Class<?> aClass = obj.getClass();
        Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            //获得set方法名
            String name = field.getName();
            String setter = "set"+ name.substring(0,1).toUpperCase() +name.substring(1);
            try {
                Method method = aClass.getMethod(setter,field.getType());
                //对日期处理（只针对LocalDate类型日期）
                if (field.getType().equals(LocalDate.class)){
                    String  str = claims.get(name).toString();
                    LocalDate parse = LocalDate.parse(str);
                    method.invoke(obj,parse);
                }else {
                    method.invoke(obj,claims.get(name));
                }

            } catch (Exception e){
            }
        }
        return obj;
    }
}
